using System.Diagnostics;
using System.Text;
using System.Text.Json;
using ChatGpt_WebApp;
using ChatGpt_WebApp.Fillter;
using ChatGpt_WebApp.ThirdApi;
using Forge.OpenAI;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting.Server.Features;
using Microsoft.Extensions.FileProviders;
//using NLog.Extensions.Logging;
using NLog.Web;

//读取配置文件
var config = new ConfigurationBuilder()
    .SetBasePath(Directory.GetCurrentDirectory())
    .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
    .Build();

AppSetting.Init(config);
TokenManager.LoadToken();

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

// 配置swagger
builder.Services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new() { Title = "ChatGpt_WebApp", Version = "v1" });
});

//配置mvc
builder.Services.AddControllers(option =>
{
    option.Filters.Add<ActionFilter>();
    option.Filters.Add<GlobalExceptionFilter>();
}).AddJsonOptions(options =>
{
    options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
    //日期格式化 yyyy-MM-dd HH:mm:ss
    options.JsonSerializerOptions.Converters.Add(new DateTimeConverter("yyyy-MM-dd HH:mm:ss"));
});


//配置跨域
builder.Services.AddCors(options =>
{
    options.AddPolicy(name: "MyCorsPolicy",
                      builder =>
                      {
                          builder.AllowAnyOrigin();
                      });
});

//配置nlog
builder.Services.AddLogging(loggingBuilder =>
{
    loggingBuilder.ClearProviders();
    loggingBuilder.SetMinimumLevel(LogLevel.Trace);
    loggingBuilder.AddNLog("nlog.config");
    builder.Host.UseNLog();
});

//配置chatgpt
builder.Services.AddPawanChatGptApi(option =>
{
    var setting = AppSetting.Current!.ChatGpt;
    if (!setting.TokenPool.Any())
    {
        throw new Exception("没有配置任何SessionToken");
    }

    setting.TokenPool.ForEach(token =>
    {
        option.AddConfig(token.Id, config =>
        {
            config.AccountType = token.IsProUser ? ChatGPT.Net.Enums.AccountType.Pro : ChatGPT.Net.Enums.AccountType.Free;
            config.SessionToken = token.SessionToken;
            config.ConfigDir = Path.Combine(builder.Environment.ContentRootPath, "ChatGptConfig", token.Account ?? "tookenId_" + token.Id.ToString());
        });
    });

});

builder.Services.AddForgeOpenAI(options => {
        options.AuthenticationInfo = AppSetting.Current!.ChatGpt.TokenPool[0].ApiKey;
        options.BaseAddress = "https://f547046a.cloudflare-proxy.pages.dev/";        
});

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("RequireIpAddress", policy =>
    {
        policy.Requirements.Add(new IpAddressRequirement(AppSetting.Current!.AdminIps));  // 允许访问的 IP 地址列表
    });
});

builder.Services.AddSingleton(f => AppSetting.Current!);
builder.Services.AddSingleton(typeof(IChatApi), typeof(PawanChatGptApi));
builder.Services.AddSingleton<IAuthorizationHandler, IpAddressAuthorizationHandler>();  // 注册授权处理程序
builder.Services.AddHttpContextAccessor();

var app = builder.Build();

//默认打开 wwwroot下的 index.html
//app.UseHttpsRedirection();

app.UseDefaultFiles();

app.UseStaticFiles();

// //生产环境下使用bin 目录下的 wwwroot
// if (!builder.Environment.IsDevelopment())
// {
//     app.UseStaticFiles(new StaticFileOptions
//     {
//         FileProvider = new PhysicalFileProvider(Path.Combine(builder.Environment.ContentRootPath, "wwwroot")),
//         RequestPath = "/wwwroot"
//     });
// }

//使用swagger
if (builder.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI(c => c.SwaggerEndpoint(" ", "ChatGpt_WebApp v1"));
}

app.Use(async (context, next) =>
{
    try
    {
        var ip = context.Connection.RemoteIpAddress!.ToString();
        if (ip == "::1")
        {
            context.Connection.RemoteIpAddress = System.Net.IPAddress.Parse("127.0.0.1");
        }
        context.Connection.RemoteIpAddress = System.Net.IPAddress.Parse(ip.Replace(":ffff:", "").Replace("f", "").Replace(":", ""));
    }
    catch (System.Exception){}

    await next();
});

app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.UseCors("MyCorsPolicy");

app.MapControllers();

await app.StartAsync();

//控制台打印启动的地址
foreach (var url in app.Urls)
{
    Console.WriteLine(url);
}

await app.WaitForShutdownAsync();
